<?php
/**
 * 棋牌控制
 */
namespace app\service;

use app\common\utils\RedisUtils;

Class Chess
{
    /**
     * 梭哈
     *
     * @var array
     */
    public $poker = [
        1,   8,  9, 10, 11, 12, 13, // 黑桃

        21, 28, 29, 30, 31, 32, 33, // 红桃

        41, 48, 49, 50, 51, 52, 53, // 梅花

        61, 68, 69, 70, 71, 72, 73  // 方块
    ];

    /**
     * 发牌key
     *
     * @var [type]
     */
    public $key;

    /**
     * 牌桌id
     *
     * @var [type]
     */
    public $tid;

    /**
     * 手牌
     *
     * @var [type]
     */
    public $handKey;

    /**
     * 玩家对应的位置
     *
     * @var [type]
     */
    public $tableKey;

    /**
     * 好牌玩家
     *
     * @var [type]
     */
    public $goodCardsKey;

    /**
     * 叫牌
     *
     * @var [type]
     */
    public $callCardsKey;

    /**
     * 数据配置
     *
     * @var [type]
     */
    public $tkey;

    /**
     * 好牌定义
     *
     * @var [type]
     */
    public $goodCards;

    public function __construct($tid)
    {
        $this->tid = $tid;
        $this->key = REDIS_LICENSING_POKER.$tid;
        $this->tkey = REDIS_TABLE_JOIN.$tid;
        $this->tableKey = REDIS_TABLE.$tid;
        $this->handKey = REDIS_PLAYER_HAND.$tid;
        $this->goodCardsKey = REDIS_GOOD_CARDS.$tid;
        $this->callCardsKey = REDIS_CALL_CARDS.$tid;
        $this->goodCardsDefined();
    }

    /**
     * 好牌定义
     *
     * @return [type] [description]
     */
    protected function goodCardsDefined()
    {
        $this->goodCards = [];

        // 同花牌设置
        $bt = $this->withFlowers(0, 7);    // 黑桃
        $ht = $this->withFlowers(7, 14);   // 红桃
        $mh = $this->withFlowers(14, 21);  // 梅花
        $fk = $this->withFlowers(21, 28);  // 方块

        array_push($this->goodCards, $bt);
        array_push($this->goodCards, $ht);
        array_push($this->goodCards, $mh);
        array_push($this->goodCards, $fk);
        array_push($this->goodCards, $this->theBomb()); // 炸弹
        array_push($this->goodCards, $this->gourd());   // 葫芦
    }

    /**
     * 同花设置
     *
     * @return [type] [description]
     */
    protected function withFlowers($start, $end)
    {
        $arr = [];
        for ($i = $start; $i < $end; $i++) {
            $arr[$i] = $this->poker[$i];
        }
        shuffle($arr);
        return array_slice($arr, 0, 5);
    }

    /**
     * 配置炸弹
     *
     * @return [type] [description]
     */
    protected function theBomb()
    {
        $all = $this->poker;
        $first = mt_rand(0, 6);
        $second = $first + 7;
        $third = $first + 14;
        $fourth = $first + 21;

        unset($all[$first], $all[$second], $all[$third], $all[$fourth]);
        $newAll = []; $count = 0;
        foreach ($all as $k => $v) {
            $newAll[$count++] = $v;
        }
        $newIdx = mt_rand(0, count($newAll)-1);
        $bomb = [
            $this->poker[$first],
            $this->poker[$second],
            $this->poker[$third],
            $this->poker[$fourth],
            $newAll[$newIdx]
        ];
        shuffle($bomb);

        return $bomb;
    }

    /**
     * 配置葫芦
     *
     * @return [type] [description]
     */
    protected function gourd()
    {
        $all = $this->poker;
        $first = mt_rand(0, 6);
        $second = $first + 7;
        $third = $first + 14;

        unset($all[$first], $all[$second], $all[$third]);
        $newAll = []; $count = 0;
        foreach ($all as $k => $v) {
            $newAll[$count++] = $v;
        }
        $fourth = mt_rand(0, count($newAll)-1);
        $fourthCrad = $newAll[$fourth];
        if ($fourthCrad > 61) {
            $fifthCrad = $fourthCrad - 20;
        } else {
            $fifthCrad = $fourthCrad + 20;
        }

        if ($fifthCrad == $this->poker[$first]
            || $fifthCrad == $this->poker[$second]
            || $fifthCrad == $this->poker[$third]) {
            return $this->gourd();
        }

        $bomb = [
            $this->poker[$first],
            $this->poker[$second],
            $this->poker[$third],
            $fourthCrad,
            $fifthCrad
        ];
        shuffle($bomb);

        return $bomb;
    }

    /**
     * 获取不重复随机数
     *
     * @param  [type] $start  [description]
     * @param  [type] $end    [description]
     * @param  [type] $number [description]
     * @return [type]         [description]
     */
    protected function getIsNotRepeatRand($start, $end, $number)
    {
        $num = mt_rand($start, $end);
        if ($num === $number) {
            return $this->getIsNotRepeatRand($start, $end, $number);
        }
        return $num;
    }

    /**
     * 洗牌
     *
     * @return [type] [description]
     */
    public function doShuffle()
    {
        $shuffleArray = $this->poker;
        shuffle($shuffleArray);

        RedisUtils::set($this->key, $shuffleArray);
        return $shuffleArray;
    }

    /**
     * 发手牌
     *
     * @return [type]       [description]
     */
    public function licensingToHand()
    {
        $cards = RedisUtils::get($this->key);       // 牌堆
        $pos  = RedisUtils::get($this->tableKey);   // 位置
        $goodsCards = RedisUtils::get($this->goodCardsKey); // 好牌
        $hand = [];

        // 人数不足不能发牌
        if (count($pos) < 2) {
            return false;
        }

        // 把好牌从牌堆取出
        if (!empty($goodsCards)) {
            $idx = mt_rand(0, count($this->goodCards) - 1);
            $goodsCards['cards'] = $this->goodCards[$idx];
            foreach ($cards as $k => $v) {
                foreach ($goodsCards['cards'] as $k1 => $v1) {
                    if ($v == $v1) {
                        unset($cards[$k]);
                    }
                }
            }
            RedisUtils::set($this->goodCardsKey, $goodsCards);
        }

        // 开始发牌
        for ($i = 0; $i < 2; $i++) {
            $status = $i === 1 ? true : false;
            foreach ($pos as $k => $v) {
                // 好牌特殊处理
                if ($k == $goodsCards['id']) {
                    $hand[$k][$i][$goodsCards['cards'][$i]] = $status;
                } else {
                    $hand[$k][$i][array_pop($cards)] = $status;
                }
            }
        }

        // 重新设置位置、手牌和牌堆
        RedisUtils::set($this->tableKey, $hand);
        RedisUtils::set($this->key, $cards);
        return $hand;
    }

    /**
     * 发牌
     *
     * @param  [type] $index 2 => 第三张 3 => 第四张 4 => 第五张
     * @return [type] [description]
     */
    public function licensing($index)
    {
        if ($index > 5 || $index < 2) {
            return false;
        }

        $cards = RedisUtils::get($this->key);       // 牌堆
        $pos  = RedisUtils::get($this->tableKey);   // 位置
        $goodsCards = RedisUtils::get($this->goodCardsKey); // 好牌

        // 开始发牌
        $status = true;
        $newPos = $pos;
        foreach ($pos as $k => $v) {
            // 判断发牌的顺序是否正确
            $count = count($v);
            if (($index == 2 && $count != 2) ||
                ($index == 3 && $count != 3) ||
                ($index == 4 && $count != 4)) {
                continue 1;
            }

            // 判断是否已经弃牌
            foreach ($v[count($v)-1] as $ck => $cv) {
                if ($cv === false) {
                    continue 2;
                }
            }

            if (!empty($goodsCards) && $k == $goodsCards['id']) {
                $newPos[$k][$index][$goodsCards['cards'][$index]] = $status;
            } else {
                $newPos[$k][$index][array_pop($cards)] = $status;
            }
        }

        // 重新设置位置、手牌和牌堆
        RedisUtils::set($this->tableKey, $newPos);
        RedisUtils::set($this->key, $cards);
        return $newPos;
    }

    /**
     * 过牌
     *
     * @param  [type] $uid [description]
     * @return [type] [description]
     */
    public function aCard($uid)
    {
        $call = RedisUtils::get($this->callCardsKey);
        $table = RedisUtils::get($this->tkey);
    }

    /**
     * 弃牌
     *
     * @param  [type] $uid [description]
     * @return [type]      [description]
     */
    public function discard($uid)
    {
        $pos  = RedisUtils::get($this->tableKey);   // 位置

        foreach ($pos as $k => &$v) {
            if ($k == $uid) {
                foreach ($v as $dk => $dv) {
                    foreach ($dv as $sk => $sv) {
                        $v[$dk][$sk] = false;
                    }
                }
            }
        }

        RedisUtils::set($this->tableKey, $pos);
        return $pos;
    }
}
